package com.gitee.kamismile.stoneComEx.util;

import io.netty.handler.ssl.SslContext;
import io.netty.handler.ssl.SslContextBuilder;
import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
import io.netty.handler.timeout.ReadTimeoutHandler;
import io.netty.handler.timeout.WriteTimeoutHandler;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.hc.client5.http.ssl.NoopHostnameVerifier;
import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactory;
import org.apache.hc.core5.http.io.SocketConfig;
import org.apache.hc.core5.ssl.SSLContexts;
import org.apache.hc.core5.ssl.TrustStrategy;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.http.client.reactive.ReactorClientHttpConnector;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.netty.http.client.HttpClient;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLException;
import java.util.concurrent.TimeUnit;
public class HttpUtils {

   private static WebClient webClient=null;
    private static RestTemplate restTemplate=null;

    public static synchronized RestTemplate getRestTemplate(int timeout)  {
        if(restTemplate!=null){
            return restTemplate;
        }
        TrustStrategy acceptingTrustStrategy = (chain, authType) -> true;
        SSLContext sslContext = null;
        try {
            sslContext = SSLContexts.custom().loadTrustMaterial(null, acceptingTrustStrategy).build();
        } catch (Exception e) {
            e.printStackTrace();
        }
        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE);
        HttpClientBuilder clientBuilder = HttpClients.custom();
        CloseableHttpClient httpClient = clientBuilder.build();
        HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
        requestFactory.setHttpClient(httpClient);
        requestFactory.setConnectionRequestTimeout(timeout*1000);
        requestFactory.setConnectTimeout(timeout*1000);
//        requestFactory.setReadTimeout(timeout*1000);
        RestTemplate restTemplate = new RestTemplate(requestFactory);
//        ClientHttpRequestInterceptor clientHttpRequestInterceptor =
//                (request, body, execution) -> {
//                    HttpHeaders headers = request.getHeaders();
//                    // 加入自定义字段
//                    headers.add("x-request-from-head-app-name", "uuid");
//                    // 保证请求继续被执行
//                    return execution.execute(request, body);
//                };
//        restTemplate.setInterceptors(Collections.singletonList(clientHttpRequestInterceptor));
        //    restTemplate.setErrorHandler(
        //        new ResponseErrorHandler() {
        //          @Override
        //          public boolean hasError(ClientHttpResponse response) throws IOException {
        //            return false;
        //          }
        //
        //          @Override
        //          public void handleError(ClientHttpResponse response) throws IOException {}
        //        });
        return restTemplate;
    }


    public static synchronized WebClient getWebClient(int timeout){
        if(webClient!=null){
            return webClient;
        }
        SslContext sslContext = null;

        try {
            sslContext=SslContextBuilder.forClient().trustManager(InsecureTrustManagerFactory.INSTANCE)
                    .build();
        } catch (SSLException e) {
           e.printStackTrace();
        }
        SslContext finalSslContext = sslContext;
        HttpClient httpClient = HttpClient.create().secure(t -> t.sslContext(finalSslContext))
                .doOnConnected(conn -> conn
                        .addHandler(new ReadTimeoutHandler(timeout, TimeUnit.SECONDS))
                        .addHandler(new WriteTimeoutHandler(timeout)));;
        webClient= WebClient.builder().clientConnector(new ReactorClientHttpConnector(httpClient)).build();
        return webClient;
    }

}
